<?php

/**
 * Description of BaseModule
 *
 * @author David Dusek
 */
require_once WWW_DIR . '/CMS/js/markitup/sets/textile/Textile.php';

use \CMS\Core,
    \CMS\Page\Models\Content,
    \CMS\Page\Models\PageConfig;

class PageModule extends \CMS\AbstractModule {
    private $handlers;
    
    public function hookAdminMenu() {
        return array("title" => "adminMenuTitle", 
                     "link" => ":Page:Page:default",
                     "img" => "btn_html.png");
    }
    
    public function hookAdminSubmenu() {
        $submenu = array(
            0 => array(
                "title" => "list",
                "link" => ":Page:Page:default",
                "icon" => "ui-icon-clipboard",
                "right" => "list",
            ),
            1 => array (
                "title" => "add",
                "link" => ":Page:Page:add",
                "icon" => "ui-icon-plus",
                "right" => "add",
            ),
            2 => array (
                "title" => "settings",
                "link" => ":Page:PageConfig:default",
                "icon" => "ui-icon-wrench",
                "right" => "config"
            )
        );
        return $submenu;
    }
            
    public function hookUserGetAcl() {
        $acl = array(
            "Page" => array(
                "name" => "page_aclTitle",
                "operations" => array(
                    "list"  => "page_aclList", 
                    "add"   => "page_aclAdd", 
                    "edit"  => "page_aclEdit", 
                    "delete" => "page_aclDelete"),
            ),
            "PageConfig" => array(
                "name" => "page_aclConfigTitle",
                "operations" => array(
                    "config" => "page_aclConfig"
                ),
            ),
        );
        
        return $acl;
    }
    
    /**
     * Podle zadane adresy se pokusi najit odpovidajici obsah. Pokud nenajde
     * vrati FALSE. Pokud najde vrati asociativni pole s informacemi
     * potrebnymi k zobrazeni stranky.
     * @param String $address Adresa pozadavku.
     * @param boolean $homepage Pokud se ma zobrazit homepage, pak je TRUE.
     * @return array|FALSE 
     */
    public function hookGetPageInfo($address, $homepage) {
        // zavola hook hookPageInit
        $this->setHandlers();
        $beforeHandlers = isset($this->handlers["beforeHandlers"]) ? $this->handlers["beforeHandlers"] : array();
        $afterHandlers = isset($this->handlers["afterHandlers"]) ? $this->handlers["afterHandlers"] : array();
        
        if ($homepage) {
            $content = $this->getHomepage();
        } else {
            $content = $this->getContentByAddress($address);
        }
        
        if (!$content || !$content->getActive()) {
            return FALSE;
        }
        
        $pageContent = $this->core->runHook("hookGetContent", $content->getContentId(), $content->getModule());        
        if (!$pageContent) {
            return FALSE;
        }
        $default = $this->em->getrepository("\CMS\Page\Models\PageConfig")->getConfig();
        $pageContent = $this->setInfo($pageContent, $default);
        
        return $pageContent;
    }
    
    /**
     * Nastaveni vychoyich hodnot do pole s nastavenim stranky, pro polozky,
     * ktere nejsou nastaveny z volani hookGetContent.
     * @param array $fromContent
     * @param PageConfig $defaults
     * @return \CMS\Page\Models\PageConfig 
     */
    private function setInfo($fromContent, PageConfig $defaults) {
        if (!isset($fromContent["title"]) || empty($fromContent["title"])) { 
            $fromContent["title"] = $defaults->title; 
        }
        if (!isset($fromContent["description"]) || empty($fromContent["description"])) { 
            $fromContent["description"] = $defaults->description; 
        }
        if (!isset($fromContent["keywords"]) || empty($fromContent["keywords"])) { 
            $fromContent["keywords"] = $defaults->keywords; 
        }
        if (!isset($fromContent["layout"]) || empty($fromContent["layout"])) { 
            $fromContent["layout"] = $defaults->layout; 
        }
        if (!isset($fromContent["style"]) || empty($fromContent["style"])) { 
            $fromContent["style"] = $defaults->style; 
        }
        if (!isset($fromContent["icon"]) || empty($fromContent["icon"])) { 
            $fromContent["icon"] = $defaults->icon; 
        }
        if (!isset($fromContent["contentType"]) || empty($fromContent["contentType"])) { 
            $fromContent["contentType"] = "text/html; charset=utf-8"; 
        }
        
        return $fromContent;
    }
    
    /**
     * Hook pro ziskani obsahu a nastaveni webove stranky.
     * @param int $id Id stranky
     * @return boolean 
     */
    public function hookGetContent($id) {
        try { 
            $page = $this->em->getRepository("\CMS\Page\Models\Page")->find($id);
        } catch ( NoResultException $e )  {
            return FALSE;
        }
        
        $textile = new Textile();
        $contentText = $textile->TextileThis($page->contentText);
        
        $content = array(
            "title" => $page->title,
            "keywords" => $page->keywords,
            "description" => $page->description,
            "content" => $contentText,
            "layout" => $page->layout,            
        );
        
        return $content;
    }    

    /**
     * Spusti hook hookPageInit nad vsemi moduly. Z vysledku si vytvori pole
     * obsahujici informaci o zaregistrovanych handlerech pro ruzne faze
     * zpracovani obsahu a ulozi je do atributu handlers. 
     */
    private function setHandlers() {
        $data = array();
        
        $handlers = $this->core->runHook("hookPageInit", null);
        if ($handlers) {
            foreach ($handlers as $handler) {
                if (isset($handler["beforeHandler"])) { $data["beforeHandlers"][] = $handler["beforeHandler"]; }
                if (isset($handler["afterHandler"])) { $data["afterHandlers"][] = $handler["afterHandler"]; }
            }
        }
        
        $this->handlers = $data;
    }
    
    /**
     * Vytvori nebo nacte objekt tridy Content, naplni ho daty a vrati.
     * Obejkt se neuklada do databaze.
     * @param array $data
     * @return \CMS\Page\Models\Content 
     */
    public function hookAddContent($data) {        
        if ($data["editedContentId"] === null) {
            $content = new Content();            
        } else {
            $content = $this->em->getRepository("\CMS\Page\Models\Content")->find($data["editedContentId"]);
        }
        
        $content->setModule($data["module"]);
        $content->setContentId($data["contentId"]);       
        $content->setAddress($data["address"]);
        
        return $content;
    }
    
    /**
     * Nastavi predany content jako homepage a predchozi homepage nastavi na
     * FALSE.
     * @param Content $content 
     */
    public function hookPageSetLikeHomepage(Content $content) {
        if (!$content->homepage) {
            $homepage = $this->getHomepage();
            if ($homepage) {
                $homepage->homepage = FALSE;                
            }
            $content->homepage = TRUE;
        }
        
        $this->em->flush();
    }
    
    /**
     * Test jestli je zadana adresa volna.
     * @param String $address Adresa pro overeni.
     * @param int $contentId Prii editaci muze byt adresa v systemu prave jednou
     * a to prave u editovaneho zaznamu.
     * @return boolean 
     */
    public function hookIsAddressAvailable($address, $contentId = FALSE) {
        $result = $this->em->getRepository("\CMS\Page\Models\Content")->findOneByAddress($address);
        $ret = FALSE;
        
        if ($result === null) {
            $ret = TRUE;            
        } else if ($contentId !== FALSE && $result->getId() == $contentId) {
            $ret = TRUE;            
        }
        
        return $ret;
    }
    
    /**
     * Vrati content s nastavenym priznakem homepage pokud existuje jinak vraci FALSE.
     * @return \CMS\Page\Models\Content|FALSE 
     */
    private function getHomepage() {
        return $this->em->getRepository("\CMS\Page\Models\Content")->getHomepage();
    }
    
    /**
     * Nalezeni obsahu podle adresy. Pokud neni naleyen zadny zaznam s pozadovanou 
     * adresou je vracono FALSE.
     * @param String $address
     * @return \CMS\Page\Models\Content|FALSE  
     */
    private function getContentByAddress($address) {
        if ($address[strlen($address) - 1] == '/') {
            $address = substr($address, 0, -1);
        }
        
        $result = $this->em->getRepository("\CMS\Page\Models\Content")->findOneByAddress($address);
        if ($result === null) {
            return FALSE;
        }
        
        
        return $result;
    }
}
